package com.beiding.editanalyzeframe;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * 一个待分析的文档
 * todo 使用KMP算法的变种分析文档的最大相同段
 * 然后递归分隔直到找到最相似代码段,最后将不相同的部分判断是删除或修改
 * 目前暂时使用二维数组求算方法
 *
 * @author 丁常磊
 * @date 2021/11/30 10:56
 */

public class Doc {

    /**
     * 所有的行
     */
    List<Line> lines;


    /**
     * 禁止自行创建
     */
    Doc() {

    }


    /**
     * 使用行号获取一个行
     *
     * @param ln
     * @return
     */
    public Line getLine(int ln) {
        //避免空指针
        if (ln >= lines.size()) {
            return null;
        }
        return lines.get(ln);
    }

    /**
     * 判断是否具有一个行
     *
     * @param ln
     * @return
     */
    public boolean hasLine(int ln) {
        return lines.size() > ln;
    }

    /**
     * 判断有多少行
     *
     * @return
     */
    public int countLines() {
        return lines.size();
    }

    public String toText() {

        StringBuilder builder = new StringBuilder();
        Iterator<Line> iterator = lines.iterator();

        if (iterator.hasNext()) {
            builder.append(iterator.next().toText());

            while (iterator.hasNext()) {
                builder.append("\n");
                builder.append(iterator.next().toText());
            }
        }

        return builder.toString();
    }

    /**
     * 子文档
     *
     * @param fromLine
     * @param lineSize
     * @return
     */
    public Doc subDoc(int fromLine, int lineSize) {
        if (fromLine >= lines.size() || fromLine + lineSize > lines.size()) {
            return null;
        }
        Doc doc = new Doc();

        //复制行
        doc.lines = new ArrayList<>();

        for (int i = 0; i < lineSize; i++) {
            doc.lines.add(this.lines.get(fromLine + i));
        }


        return doc;
    }


    /**
     * 行不可编辑
     *
     * @return
     */
    public List<Line> getLines() {
        return Collections.unmodifiableList(this.lines);
    }

    /**
     * 比较两个文件
     * 找到
     * 1. 新增行
     * 2. 删除行
     *
     * @param target
     * @return
     */
    public CompareResult compare(Doc target,AnalyzeConfig analyzeConfig) {
        return DocUtils.compare(this.lines, target.getLines(),analyzeConfig);
    }

    /**
     * 比对两个文件并生成一个
     * 并将
     *
     * @return
     */
    public List<AnalyseLine> analyse(Doc target) {
        return analyse(target,new AnalyzeConfig());

    }

    public List<AnalyseLine> analyse(Doc target,AnalyzeConfig analyzeConfig) {

        //比对结果
        CompareResult compare = compare(target,analyzeConfig);

        return DocUtils.createAnalyseLines(compare);

    }

    @Override
    public String toString() {
        return toText();
    }


}
